using TFlex.Model;
using TFlex.Model.Model3D.Visual.Manipulators;

namespace External3D
{
	// Manipulator for dynamic editing of local coordinate system
	//
	// Манипулятор для редактирования положения локальной системы координат
	public class LCSManipulator : BaseManipulator
	{
		// Local coordinate system
		//
		// Локальная система координат
		protected LCS m_lcs = new LCS();
		public LCS Local
		{
			get { return new LCS(m_lcs); }
			set { m_lcs = new LCS(value); }
		}

		// Manipulator with which the user actually interacts
		//
		// Манипулятор, посредством которого пользователь задаёт положение и ориентацию локальной системы координат
		protected CoordSystemManipulator m_manipulator = null;

		// Constructs a manipulator
		//
		// Конструктор
		public LCSManipulator(Document document, External3DPlugin plugin)
			: base(document, plugin)
		{
		}

		// Activates this manipulator
		//
		// Запустить манипулятор
		public virtual void Start()
		{
			if (m_manipulator != null)
				return;

			m_manipulator = new CoordSystemManipulator();
			m_manipulator.ResetCoordSystem(m_lcs.O, m_lcs.X, m_lcs.Y, m_lcs.Z);
			m_manipulator.ModificationEnqueued += OnUpdate;
			m_manipulator.ModificationCommited += OnCommit;

			BaseActivated(BaseManipulator.IDManipulator.Point);
			BaseActivated(BaseManipulator.IDManipulator.Orientation);
		}

		// Deactivates this manipulator
		//
		// Остановить манипулятор
		public void Stop()
		{
			if (m_manipulator == null)
				return;

			m_manipulator.Dispose();
			m_manipulator = null;
		}

		// This method is called when the user moves the manipulator
		//
		// Изменение параметров манипулятора
		private void OnUpdate(object sender, ModificationEnqueuedEventArgs args)
		{
			CoordSystemManipulator manipulator = args.Manipulator as CoordSystemManipulator;
			if (manipulator == null)
				return;

			m_lcs.O = manipulator.GetPendingOrigin();
			BaseUpdated(BaseManipulator.IDManipulator.Point);

			m_lcs.X = manipulator.GetPendingDirection(0);
			m_lcs.Y = manipulator.GetPendingDirection(1);
			BaseUpdated(BaseManipulator.IDManipulator.Orientation);
		}

		// This method is called when the user finishes moving the manipulator
		//
		// Конец изменения параметров манипулятора
		private void OnCommit(object sender, ModificationCommitedEventArgs args)
		{
			CoordSystemManipulator manipulator = args.Manipulator as CoordSystemManipulator;
			if (manipulator == null)
				return;

			m_lcs.O = manipulator.GetCommitedOrigin();
			BaseReleased(BaseManipulator.IDManipulator.Point);

			m_lcs.X = manipulator.GetCommitedDirection(0);
			m_lcs.Y = manipulator.GetCommitedDirection(1);
			BaseReleased(BaseManipulator.IDManipulator.Orientation);
		}
	};
}
